/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package types;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import rules.Rule;
import utils.RuleHelper;

/**
 * die klasse speichert für jedes leeres feld die anwendbare Rules
 * @author ali
 */
public class MatrixApplicableRules {

    Collection [][] applicableRules  = new ArrayList[9][9];
    Collection allRules = new ArrayList();

    /**
     *
     * @param allRules: alle verfügbare regeln
     */
    public MatrixApplicableRules(Collection allRules) {
        this.allRules = allRules;

        //initalisierung der 2 dimensionale Arrays von collections!
        for (int i = 0; i<9; i++)
        {
            for (int j = 0; j<9; j++)
            {
                this.applicableRules[i][j] = new ArrayList();
            }

        }
    }

    public Collection getApplicableRules (int x, int y)
    {
        return (this.applicableRules[x][y]);
    }

    /**
     * refresh the whole applicableRules collection for the currentConf
     * must be invoked each time an empty field is filled.
     * @param currentConf
     */
    public void refreshApplicableRules(ISudokuMatrix currentConf)
    {
        this.resetAllRuleCollections();
        for (int i = 0; i<9; i++)
        {
            for (int j = 0; j<9; j++)
            {
                if ((Integer)currentConf.getElementAt(i, j)!=0)
                    continue;

                System.out.println("Filtering applicable rules for field: "+i+","+j);
                Iterator iter = this.allRules.iterator();
                while (iter.hasNext())
                {
                    Rule rule = (Rule) iter.next();
                    Rule clonedRule = RuleHelper.cloneRule(rule);


                    if (clonedRule.isApplicable(i, j, currentConf))
                    {
                        System.out.println("\tRule "+clonedRule.getName()+" applicable");
                        this.applicableRules[i][j].add(clonedRule);
                    }
                }
//                //sortieren der für einen feld anwendbare rules nach gewicht!
//                if ((this.applicableRules[i][j]).size()>1)
//                {
//                    int size = (this.applicableRules [i][j]).size();
//
//                    System.out.println("before sorting "+i+", "+j);
//
//                    Iterator iter1 = this.applicableRules[i][j].iterator();
//                    while (iter1.hasNext())
//                    {
//                        Rule rl = (Rule) iter1.next();
//                        System.out.println(rl.getName()+" cost: "+rl.getWeight(rl.getQuadrat()));
//                    }
//
//                    Collections.sort((ArrayList<Rule>) this.applicableRules[i][j]);
//
//                    System.out.println("after sorting");
//                    Iterator iter2 = this.applicableRules[i][j].iterator();
//                    while (iter2.hasNext())
//                    {
//                        Rule rl = (Rule) iter2.next();
//                        System.out.println(rl.getName()+" cost: "+rl.getWeight(rl.getQuadrat()));
//                    }
//
//                }
            }
        }
    }

    private void resetAllRuleCollections()
    {
         for (int i = 0; i<9; i++)
        {
            for (int j = 0; j<9; j++)
            {
                if (this.applicableRules[i][j].size()!=0)
                {
                    applicableRules[i][j].clear();
                }
            }
         }
    }
}
